# Copyright (C) 2009 Paul Rudin
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
""" utility functions for models"""

import OpenGL.GL as gl

def bounding_box(model):
    """ returns opposite corners of the cuboid containing all the
    points of model. Note that we do not check to see if all of the
    points are actually used.
    """
    return model.points.min(axis = 0), model.points.max(axis = 0)

def normalize(model):
    """ scale and shift model so that it entirely contained within the
    unit cube. (With a small amount of space so that we don't actually
    touch the unit cube anywhere).
    """
    bmin, bmax = bounding_box(model)
    length = bmax - bmin
    space = 0.95
    scale_factor = space / length.max()
    model.points -= bmin
    model.points *= scale_factor
    model.points += (1.0 - space)/2.0
    return model
    


def rationalize(model):
    """Remove points that are not referenced by any polygon, and
    adjust polygons so that model geometry is unchanged"""

    

def draw(model):
    """ execute the opengl commands to draw model
    """
    
    gl.glEnableClientState(gl.GL_VERTEX_ARRAY)
    gl.glVertexPointerd(model.points)
    points_per_poly = len(model.polys[0])

    if points_per_poly in (3, 4):
        element_type = (gl.GL_QUADS
                        if points_per_poly == 4
                        else gl.GL_TRIANGLES)
        gl.glDrawElementsus(element_type, model.polys.ravel())

    else:
        for poly in model.polys:
            gl.glDrawElements(gl.GL_POLYGON,
                              points_per_poly,
                              gl.GL_UNSIGNED_SHORT,
                              poly)


